package cn.kpi.common.Excel.export.impl;

import cn.kpi.common.Excel.domain.SubheadModel;
import cn.kpi.common.Excel.export.domain.common.ExportCell;
import cn.kpi.common.Excel.export.domain.common.ExportInfo;
import cn.kpi.common.Excel.export.exception.FileExportException;
import cn.kpi.common.Excel.export.service.IFileExportor;
import cn.kpi.common.Excel.util.ReflectionUtils;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.math.BigDecimal;
import java.util.*;

/**
 * Create by liuyong on 2017/11/3
 */

public class ExcelExportor implements IFileExportor {

    private static int defaultWidth =8 * 512;

    @Override
    public Workbook getExportResult(List<?> data, List<ExportCell> exportCells, SubheadModel subheadingVo) throws FileExportException {
        Workbook workbook = new XSSFWorkbook();
        return getWorkbook(data, exportCells, subheadingVo, workbook);
    }

    public Workbook addSheet(Workbook workbook, List<?> data, List<ExportCell> exportCells, SubheadModel subheadingVo) throws FileExportException {
        return getWorkbook(data, exportCells, subheadingVo, workbook);
    }

    private Workbook getWorkbook(List<?> data, List<ExportCell> exportCells, SubheadModel subheadingVo, Workbook workbook) throws FileExportException {
        Integer mergedColumnNum = exportCells.size();
        //sheetName
        Sheet sheet = workbook.createSheet(subheadingVo.getSheetName());
        //todo:这里应该提成一个公共类，应对各种类型的表头
        Row hearRow = sheet.createRow(1);
        //一级标题
        createHeaderRow(workbook, hearRow, sheet, subheadingVo.getHeader(),mergedColumnNum);
        Row infoRow = sheet.createRow(2);
        //这里加入二级标题
        List<ExportInfo> infoList = new ArrayList<>();
        createInfoRow(workbook, infoRow, infoList);

        //这里插入行
        Row titleRow = sheet.createRow(3);
        createTitleRow(workbook, titleRow, exportCells,subheadingVo);

        //循环数据开始
        if (List.class.isAssignableFrom(data.getClass())) {
            if (!data.isEmpty()) {
                if (data.get(0) instanceof Map) {
                    createContentRowsByMap(workbook, (List<Map>) data, exportCells, sheet);
                } else {
                    createContentRowsByBean(workbook, (List<Object>) data, exportCells, sheet);
                }
            }
        } else {
            throw new FileExportException("传入的data数据格式有误，请检查是否属于list");
        }

        //自动适应调整
        sheet.autoSizeColumn((short)0);
        sheet.autoSizeColumn((short)1); //调整第二列宽度
        sheet.autoSizeColumn((short)2); //调整第三列宽度
        sheet.autoSizeColumn((short)3); //调整第四列宽度
        return workbook;
    }

    private Workbook createContentRowsByMap(Workbook workbook, List<Map> dataList, List<ExportCell> exportCells, Sheet sheet) throws FileExportException {
        if (!dataList.isEmpty()) {
            int rowNum = 4;
            CellStyle cellStyle = createHeadStyle(workbook);
            for (Map map : dataList) {
                Row row = sheet.createRow(rowNum);
                row.setHeightInPoints(23.0F);
                for (int colNum = 0; colNum < exportCells.size(); colNum++) {
//                    Cell cell = row.createCell(colNum + 3);
                    Cell cell = row.createCell(colNum);//0 列开始
                    cell.setCellStyle(cellStyle);
                    ExportCell exportCell = exportCells.get(colNum);
                    Object obj = null;
                    obj = map.get(exportCell.getAlias());
                    setCellValue(obj, cell,sheet,colNum);
                }
                rowNum++;
            }
        }
        return workbook;
    }

    private static void createContentRowsByBean(Workbook workbook, List<Object> dataList, List<ExportCell> exportCells, Sheet sheet) throws FileExportException {
        int rowNum = 4;
        if (!dataList.isEmpty()) {
            CellStyle cellStyle = createCellStyle(workbook);
            for (Object t : dataList) {
                Row row = sheet.createRow(rowNum);
                row.setHeightInPoints(23.0F);
                for (int colNum = 0; colNum < exportCells.size(); colNum++) {
//                    Cell cell = row.createCell(colNum + 3);
                    Cell cell = row.createCell(colNum );
                    cell.setCellStyle(cellStyle);
                    ExportCell exportCell = exportCells.get(colNum);
                    Object obj = null;
                    try {
                        obj = ReflectionUtils.executeMethod(t, ReflectionUtils.returnGetMethodName(exportCell.getAlias()));
                    } catch (Exception e) {
                        throw new FileExportException("执行executeMethod  出错 Alias is " + exportCell.getAlias() + " at " + e.getMessage());
                    }
                    setCellValue(obj, cell,sheet,colNum);//增加值
                }
                ++rowNum;
                System.out.println(rowNum);
            }
        }
    }

    private static void setCellValue(Object obj, Cell cell, Sheet sheet, int colnumIndex) throws FileExportException {
        if (obj != null) {
            BigDecimal bigDecimal = null;
            String classType = obj.getClass().getName();
            if (classType.endsWith("String")){
                cell.setCellValue((String) obj);
            }
            else if (("int".equals(classType)) || (classType.equals("java.lang.Integer")))
                cell.setCellValue(((Integer) obj).intValue());
            else if (("double".equals(classType)) || (classType.equals("java.lang.Double"))) {
                bigDecimal = new BigDecimal(((Double) obj).doubleValue());
                bigDecimal = bigDecimal.setScale(2,4);
                cell.setCellValue(bigDecimal.doubleValue());
            } else if (("float".equals(classType)) || (classType.equals("java.lang.Float"))) {
                bigDecimal = new BigDecimal(((Float) obj).floatValue());
                bigDecimal =bigDecimal.setScale(2,4);
                cell.setCellValue(bigDecimal.doubleValue());
            } else if ((classType.equals("java.util.Date")) || (classType.endsWith("Date")))
                cell.setCellValue(cn.kpi.common.Excel.util.DateUtil.dateToString((Date) obj, cn.kpi.common.Excel.util.DateUtil.YYYYMMDDHHMMSS));
            else if (classType.equals("java.util.Calendar"))
                cell.setCellValue((Calendar) obj);
            else if (("char".equals(classType)) || (classType.equals("java.lang.Character")))
                cell.setCellValue(obj.toString());
            else if (("long".equals(classType)) || (classType.equals("java.lang.Long")))
                cell.setCellValue(((Long) obj).longValue());
            else if (("short".equals(classType)) || (classType.equals("java.lang.Short")))
                cell.setCellValue(((Short) obj).shortValue());
            else if (classType.equals("java.math.BigDecimal")) {
                bigDecimal = (BigDecimal) obj;
                bigDecimal = new BigDecimal(bigDecimal.doubleValue());
                cell.setCellValue(bigDecimal.doubleValue());
            } else {
                throw new FileExportException("data type error !  obj is " + obj);
            }
        }
    }

    //一级标题
    private static void createHeaderRow(Workbook workbook, Row row, Sheet sheet, String header, Integer mergedNum) {
        CellStyle cellStyle = workbook.createCellStyle();
        Font font = workbook.createFont();
        font.setColor((short) 0);
        font.setBoldweight((short) 700);
        font.setFontHeight((short) 340);
        cellStyle.setFont(font);
        cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直
        cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 水平
//        Cell cell = row.createCell((short) 3);
        Cell cell = row.createCell((short) 0);
        cell.setCellValue(header);
        cell.setCellStyle(cellStyle);
        CellRangeAddress region1 = new CellRangeAddress(1, 1, (short) 0, mergedNum);
        sheet.addMergedRegion(region1);

    }
    //二级标题
    private static void createInfoRow(Workbook workbook, Row row, List<ExportInfo> ExportInfos) {
        short cellIndex = 5;
        CellStyle cellStyle = workbook.createCellStyle();
        Font font = workbook.createFont();
        cellStyle.setFont(font);
        for (ExportInfo info : ExportInfos) {
            Cell cell = row.createCell((short) cellIndex);
            cell.setCellValue(info.getTitle() + ":" + info.getValue());
            cell.setCellStyle(cellStyle);
            ++cellIndex;
        }
    }
    //列名
    private static void createTitleRow(Workbook workbook, Row row, List<ExportCell> exportCells,SubheadModel subheadingVo) {
        int sq = 0;
        if(subheadingVo.getHeader().equals("津贴补助表")){
         String sheetName = subheadingVo.getSheetName();
         if(sheetName.contains("1")){
             sq =1;
         }
        if(sheetName.contains("2")){
            sq =2;
        }
        if(sheetName.contains("3")){
            sq =3;
        }
        if(sheetName.contains("4")){
            sq =4;
        }
        }
        CellStyle style = createHeadStyle(workbook);
        row.setHeightInPoints(25.0F);
        Font font = workbook.createFont();
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        style.setFont(font);
        int i = 0;
        for (ExportCell exportCell : exportCells) {
//            Integer columnWidth = exportCell.getTitle().getBytes().length*256;//todo:动态大小，未起作用
            String title = exportCell.getTitle();
            if(sq!=0){
                title = TitleRowChangeMonth(title,sq);
            }
            Cell cell = row.createCell(i);
            cell.setCellValue(title);
            cell.setCellStyle(style);
            ++i;
        }
    }

    private static String TitleRowChangeMonth(String month,int quarter){
        if(quarter==1){
           month= month.replace("七","一");
            month= month.replace("八","二");
            month=month.replace("九","三");
        }
        if(quarter==2){
            month=month.replace("七","四");
            month=month.replace("八","五");
            month=month.replace("九","六");
        }
        if(quarter==4){
            month=month.replace("七","十");
            month=month.replace("八","十一");
            month=month.replace("九","十二");
        }


        return  month;
    }


    private static CellStyle createHeadStyle(Workbook workbook) {
        CellStyle style = workbook.createCellStyle();
        //TODO 使用新版本poi
        style.setAlignment((short) 2);
        style.setVerticalAlignment((short) 1);
        style.setFillForegroundColor((short) 55);
        style.setFillPattern((short) 1);
        style.setBorderBottom((short) 1);
        style.setBorderLeft((short) 1);
        style.setBorderRight((short) 1);
        style.setBorderTop((short) 1);
        style.setWrapText(true);
        return style;
    }

    private static CellStyle createCellStyle(Workbook workbook) {
        CellStyle style = workbook.createCellStyle();
        //TODO 使用新版本poi
        style.setAlignment((short) 2);
        style.setVerticalAlignment((short) 1);
        style.setFillForegroundColor((short) 9);
        Font font = workbook.createFont();
        font.setColor((short) 8);
        font.setFontHeightInPoints((short) 12);
        style.setWrapText(true);
        //加上边框
        style.setBorderBottom((short) 1);
        style.setBorderLeft((short) 1);
        style.setBorderRight((short) 1);
        style.setBorderTop((short) 1);
        return style;
    }

    private static CellStyle createCellLeftStyle(Workbook workbook) {
        CellStyle style =  createCellStyle(workbook);
        //TODO 使用新版本poi
        //样式居左
        style.setVerticalAlignment(HSSFCellStyle.ALIGN_LEFT);// 居左
        style.setAlignment(HSSFCellStyle.ALIGN_LEFT);// 水平
        return style;
    }

    private static CellStyle createCellRightStyle(Workbook workbook) {
        CellStyle style =  createCellStyle(workbook);
        //TODO 使用新版本poi
        //样式居右
        style.setVerticalAlignment(HSSFCellStyle.ALIGN_RIGHT);// 居左
        style.setAlignment(HSSFCellStyle.ALIGN_RIGHT);// 水平
        return style;
    }

//    private static void setAutoColumnWidth(Sheet sheet, int columnIndex, Object obj){
//        if(obj != null) {
//           int width = obj.toString().getBytes().length*320;
//            if (sheet.getColumnWidth(columnIndex) < width && width > defaultWidth)
//                sheet.setColumnWidth(columnIndex, width);
//            else if(sheet.getColumnWidth(columnIndex)<defaultWidth)
//                sheet.setColumnWidth(columnIndex, defaultWidth);
//        }
//        else{
//             if(sheet.getColumnWidth(columnIndex)<defaultWidth)
//                 sheet.setColumnWidth(columnIndex, defaultWidth);
//        }
//    }
}

